DROP ROLE IF EXISTS role_bypass_test;
-- start_ignore
DROP RESOURCE GROUP rg_bypass_test;
-- end_ignore

--
-- setup
--

CREATE RESOURCE GROUP rg_bypass_test WITH
  (concurrency=2, cpu_rate_limit=20, memory_limit=20, memory_shared_quota=50);
CREATE ROLE role_bypass_test RESOURCE GROUP rg_bypass_test;

CREATE OR REPLACE FUNCTION repeatPalloc(int, int) RETURNS int AS
'@abs_builddir@/../regress/regress@DLSUFFIX@', 'repeatPalloc'
LANGUAGE C READS SQL DATA;

CREATE OR REPLACE FUNCTION hold_memory(int, int) RETURNS int AS $$
    SELECT * FROM repeatPalloc(1, $2)
$$ LANGUAGE sql;

CREATE OR REPLACE VIEW eat_memory_on_qd_small AS
    SELECT hold_memory(0,12);

CREATE OR REPLACE VIEW eat_memory_on_qd_large AS
    SELECT hold_memory(0,100);

CREATE OR REPLACE VIEW eat_memory_on_one_slice AS
	SELECT count(null)
	FROM
	gp_dist_random('gp_id') t1
	WHERE hold_memory(t1.dbid,4)=0
	;

CREATE OR REPLACE VIEW eat_memory_on_slices AS
	SELECT count(null)
	FROM
	gp_dist_random('gp_id') t1,
	gp_dist_random('gp_id') t2
	WHERE hold_memory(t1.dbid,4)=0
	  AND hold_memory(t2.dbid,4)=0
	;

CREATE OR REPLACE FUNCTION round_test(float, integer) RETURNS float AS $$
	SELECT round($1 / $2) * $2
$$ LANGUAGE sql;

CREATE OR REPLACE VIEW memory_result AS
	SELECT rsgname, ismaster, round_test(avg(memory_usage), 1) AS avg_mem
	FROM(
		SELECT rsgname,
		       CASE (j->'key')::text WHEN '"-1"'::text THEN 1 ELSE 0 END AS ismaster,
		       ((j->'value')->>'used')::int AS memory_usage
		FROM(
			SELECT rsgname, row_to_json(json_each(memory_usage::json)) AS j FROM
			gp_toolkit.gp_resgroup_status
			WHERE rsgname='rg_bypass_test'
		    )a
		)b GROUP BY (rsgname, ismaster) ORDER BY rsgname, ismaster;

GRANT ALL ON eat_memory_on_qd_small TO role_bypass_test;
GRANT ALL ON eat_memory_on_qd_large TO role_bypass_test;
GRANT ALL ON eat_memory_on_one_slice TO role_bypass_test;
GRANT ALL ON eat_memory_on_slices TO role_bypass_test;
GRANT ALL ON memory_result TO role_bypass_test;

--
-- SET command should be bypassed
--

ALTER RESOURCE GROUP rg_bypass_test SET concurrency 0;
61: SET ROLE role_bypass_test;
61&: SELECT 1;
ALTER RESOURCE GROUP rg_bypass_test set concurrency 1;
61<:
ALTER RESOURCE GROUP rg_bypass_test set concurrency 0;
61: SET enable_hashagg to on;
61: SHOW enable_hashagg;
61: invalid_syntax;
61q:

--
-- gp_resource_group_bypass
--

ALTER RESOURCE GROUP rg_bypass_test SET concurrency 0;
61: SET ROLE role_bypass_test;
61: SET gp_resource_group_bypass to on;
61: SHOW gp_resource_group_bypass;
61: CREATE TABLE table_bypass_test (c1 int);
61: INSERT INTO  table_bypass_test SELECT generate_series(1,100);
61: SELECT count(*) FROM table_bypass_test;
61: DROP TABLE table_bypass_test;
61: SET gp_resource_group_bypass to off;
61: SHOW gp_resource_group_bypass;
61q:

--
-- gp_resource_group_bypass is not allowed inside a transaction block
--

61: BEGIN;
61: SET gp_resource_group_bypass to on;
61: ABORT;
61q:

--
-- gp_resource_group_bypass is not allowed inside a function
--

DROP FUNCTION IF EXISTS func_resgroup_bypass_test(int);
CREATE FUNCTION func_resgroup_bypass_test(c1 int) RETURNS INT AS $$
	SET gp_resource_group_bypass TO ON; /* inside a function */
	SELECT 1
$$ LANGUAGE SQL;
SELECT func_resgroup_bypass_test(1);
DROP FUNCTION func_resgroup_bypass_test(int);


--
-- memory limit in bypass mode, on qd
--

61: SET ROLE role_bypass_test;
61: SET gp_resource_group_bypass to on;
61: BEGIN;
61: SELECT * FROM eat_memory_on_qd_small;
SELECT * FROM memory_result;
61: SELECT * FROM eat_memory_on_qd_large;
SELECT * FROM memory_result;
61: ABORT;
61: BEGIN;
SELECT 1 FROM memory_result where avg_mem > 10 and ismaster = 1;
61q:

--
-- memory limit in bypass mode, on one slice
--

61: SET ROLE role_bypass_test;
61: SET gp_resource_group_bypass to on;
61: BEGIN;
61: SELECT * FROM eat_memory_on_one_slice;
SELECT * FROM memory_result;
61: SELECT * FROM eat_memory_on_one_slice;
SELECT * FROM memory_result;
61: SELECT * FROM eat_memory_on_one_slice;
SELECT * FROM memory_result;
61: ABORT;
61: BEGIN;
SELECT * FROM memory_result;
61q:

--
-- memory limit in bypass mode, on slices
--

61: SET ROLE role_bypass_test;
61: SET gp_resource_group_bypass to on;
61: BEGIN;
61: SELECT * FROM eat_memory_on_slices;
SELECT * FROM memory_result;
61: SELECT * FROM eat_memory_on_slices;
SELECT * FROM memory_result;
61: SELECT * FROM eat_memory_on_slices;
SELECT * FROM memory_result;
61: ABORT;
61: BEGIN;
SELECT * FROM memory_result;
61q:

--
-- gp_resgroup_status.num_running is updated in bypass mode
--

61: SET ROLE role_bypass_test;
61: SET gp_resource_group_bypass to on;
61&: SELECT pg_sleep(10);
62: SET ROLE role_bypass_test;
62: SET gp_resource_group_bypass to on;
62&: SELECT pg_sleep(20);
SELECT num_running FROM gp_toolkit.gp_resgroup_status
  WHERE rsgname='rg_bypass_test';
SELECT pg_cancel_backend(pid) FROM pg_stat_activity
  WHERE rsgname='rg_bypass_test';
61<:
62<:
61q:
62q:

--
-- pg_stat_activity is updated in bypass mode
--

61: SET ROLE role_bypass_test;
61: SET gp_resource_group_bypass to on;
61&: SELECT pg_sleep(10);
62: SET ROLE role_bypass_test;
62: SET gp_resource_group_bypass to on;
62&: SELECT pg_sleep(20);
SELECT query FROM pg_stat_activity
  WHERE rsgname='rg_bypass_test';
SELECT pg_cancel_backend(pid) FROM pg_stat_activity
  WHERE rsgname='rg_bypass_test';
61<:
62<:
61q:
62q:

--
-- cleanup
--

REVOKE ALL ON eat_memory_on_qd_small FROM role_bypass_test;
REVOKE ALL ON eat_memory_on_qd_large FROM role_bypass_test;
REVOKE ALL ON eat_memory_on_one_slice FROM role_bypass_test;
REVOKE ALL ON eat_memory_on_slices FROM role_bypass_test;
REVOKE ALL ON memory_result FROM role_bypass_test;

DROP ROLE role_bypass_test;
DROP RESOURCE GROUP rg_bypass_test;

-- vi:filetype=sql:
